/**
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-09-C-0002, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 * 
 * (c) 2009 The MITRE Corporation. All Rights Reserved.
 *
 * SPMIF to OPNET Translator
 * Author: ewalters
 * Created: 1:31:06 PM, Aug 3, 2007
 * MITRE Corporation
 */
package com.mitre.spmif2opnet.analysis;

import java.util.Hashtable;

/**
 * Unique identifier for each S-PMIF element (node).
 * In a way, this provides a unique name-space for discussing nodes, especially
 * with respect to resolving what S-PMIF variables (symbols) point to.
 */
public class Identifier {
	/**
	 * What file is the node located in?
	 */
	private String _file_name;
	/**
	 * What project in the file is the node in?
	 */
	private String _project_name;
	/** 
	 * What scenario in the project is the node in?
	 */
	private String _scenario_name;
	/** 
	 * What graph in the scenario is the node in?
	 */
	private String _graph_id;
	/** 
	 * Unique identifier for the node
	 */
	private String _node_id;

	/**
	 * Default constructor
	 */
	public Identifier() {
		_file_name = "";
		_project_name = "";
		_scenario_name = "";
		_graph_id = "";
		_node_id = "";
	}
	
	/**
	 * Copy constructor
	 * @param id source identifier
	 */
	public Identifier(Identifier id) {
		_file_name = id.getFileName();
		_project_name = id.getProjectName();
		_graph_id = id.getGraphId();
		_scenario_name = id.getScenarioName();
		_node_id = id.getNodeId();
	}
	
	// We handle the members exclusively through accessors and
	//  mutators (not the constructor)

	/**
	 * File name mutator 
	 * @param s the file name
	 */
	public void setFileName(String s) {
		_file_name = s;
	}
	
	/**
	 * File name accessor
	 * @return the file name
	 */
	public String getFileName() {
		return _file_name;
	}

	/**
	 * Project name mutator 
	 * @param s the file name
	 */
	public void setProjectName(String s) {
		_project_name = s;
	}
	
	/**
	 * Project name accessor
	 * @return the project name
	 */
	public String getProjectName() {
		return _project_name;
	}

	/**
	 * Scenario name mutator 
	 * @param s the scenario name
	 */
	public void setScenarioName(String s) {
		_scenario_name = s;
	}
	
	/**
	 * Scenario name accessor
	 * @return the scenario name
	 */
	public String getScenarioName() {
		return _scenario_name;
	}

	/**
	 * Graph id mutator 
	 * @param s the graph id
	 */
	public void setGraphId(String s) {
		_graph_id = s;
	}
	
	/**
	 * Graph id accessor
	 * @return the graph id
	 */
	public String getGraphId() {
		return _graph_id;
	}

	/**
	 * Node id mutator 
	 * @param s the node id
	 */
	public void setNodeId(String s) {
		_node_id = s;
	}
	
	/**
	 * Node id accessor
	 * @return the node id
	 */
	public String getNodeId() {
		return _node_id;
	}

	/** 
	 * Dump the entire identifier in a canonical manner.
	 * Note that this is unique enough to be used as a hash key with no fuss
	 * @return the string
	 */
	public String toString() {
		return _file_name + ":"
			+ _project_name + "."
			+ _scenario_name + "."
			+ _graph_id + "."
			+ _node_id;
	}
	
	/**
	 * Equality test
	 * Note: File id is not used for equality
	 * @param o object to test
	 * @return is it equal
	 */
	public boolean equals(Object o) {
		if (!(o instanceof Identifier)) return false;
		Identifier id = (Identifier) o;
		return (this._project_name.equals(id.getProjectName())
				&& this._scenario_name.equals(id.getScenarioName())
				&& this._graph_id.equals(id.getGraphId())
				&& this._node_id.equals(id.getNodeId()));
	}

	/**
	 * Is the file name valid?
	 * @return is it?
	 */
	public boolean validFileName() {
		return (_file_name != null && (!_file_name.equals("")));
	}
	
	// This is logic for producing unique graph and node id's in the case of copying!
	private static Hashtable<String, Integer> _node_ids = new Hashtable<String, Integer>();
	private static Hashtable<String, Integer> _graph_ids = new Hashtable<String, Integer>();
	
	/**
	 * Gives a unique node name different from the input identifier
	 * @param node_id the node to check
	 * @return the new id
	 */
	public static String newNodeId(String node_id) {
		if (!_node_ids.containsKey(node_id)) {
			_node_ids.put(node_id, 0);
		} 
		int i = _node_ids.get(node_id).intValue();
		String id_new = node_id + "_" + i;
		_node_ids.put(node_id, i + 1);
		return id_new;
	}

	/**
	 * Gives a unique graph name different from the input identifier
	 * @param node_id the graph to check
	 * @return the new id
	 */
	public static String newGraphId(String graph_id) {
		if (!_graph_ids.containsKey(graph_id)) {
			_graph_ids.put(graph_id, 0);
		} 
		int i = _graph_ids.get(graph_id).intValue();
		String id_new = graph_id + "_" + i;
		_graph_ids.put(graph_id, i + 1);
		return id_new;
	}

	
}
